package com.fyyg.service;

import com.fyyg.dal.TSysSequenceMapper;
import com.fyyg.interfaces.TSysSequenceService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * @author hang.ouyang
 * @date 2016-04-15 17:07
 */
@Service("sysSequenceService")
public class TSysSequenceServiceImpl implements TSysSequenceService {
    private final static Logger logger = LogManager.getLogger(TSysSequenceServiceImpl.class);

    private ConcurrentHashMap<String,LinkedBlockingQueue<Integer>> seqMap = new ConcurrentHashMap<>();

    @Autowired
    private TSysSequenceMapper sequenceMapper;

//    @Override
//    public String nextSequenceNo(String skey) {
//        synchronized (skey){
//            Integer sequenceNo = sequenceMapper.selectNextVal(skey);
//            String seq = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date())+sequenceNo;
//            return seq;
//        }
//    }

//    @Override
//    public Integer nextSeuenceId(String key) {
//        synchronized (key) {
//            logger.info("【分配序列号】for key\t"+key+"\tstart...");
//            LinkedBlockingQueue<Integer> queue = seqMap.get(key);
//            if (queue == null || queue.isEmpty()){
//                queue = new LinkedBlockingQueue();
//                seqMap.put(key, queue);
//            }
//            if(queue.size() <= 50){
//                LoadSeqThread loadSeqThread = new LoadSeqThread();
//                loadSeqThread.setKey(key);
//                new Thread(loadSeqThread).start();
//            }
//            try {
//                Integer val =  seqMap.get(key).poll(2, TimeUnit.SECONDS);//两秒则超时
//                logger.info("【分配序列号】for key\t"+key+"\t with seq "+val+"\t剩余号码池大小为\t"+seqMap.get(key).size());
//                return val;
//            } catch (Exception e) {
//                logger.error("【分配序列号】for key	"+key+"	失败\t"+e.getMessage());
//            }
//            return null;
//        }
//    }



    class LoadSeqThread implements Runnable{
        private String key;

        public String getKey() {
            return key;
        }

        public void setKey(String key) {
            this.key = key;
        }

        @Override
        public void run() {
            logger.info("【分配序列号】for key\t"+key+"\t load from db");
            String seqStr = sequenceMapper.selectSeqStr(getKey());
            Integer concurValue = Integer.parseInt(seqStr.split(",")[0]);
            Integer incrValue = Integer.parseInt(seqStr.split(",")[1]);
            LinkedBlockingQueue<Integer> queue = seqMap.get(getKey());
            for (Integer i = 0; i < incrValue; i++) {
                concurValue += 1;
                queue.offer(concurValue);
            }
            logger.info("【分配序列号】for key\t"+key+"\t load from db with size "+incrValue);
        }
    }
}

